import 'dart:async';
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hockey/jzx_apps.dart';
import 'package:hockey/jzx_models.dart';
import 'package:hockey/models/jzx_comment_data.dart';
import 'package:hockey/services/jzx_app.dart';
import 'package:hockey/services/jzx_config.dart';
import 'package:hockey/services/jzx_user.dart';
import 'package:lifecycle/lifecycle.dart';
import 'package:video_player/video_player.dart';

import '../../widgets/dialogs/jzx_options_sheet.dart';

class JzxVideoController extends GetxController {
  PageController pageController = PageController();

  ScrollController commentScorller = ScrollController();

  /// 当前页
  int pageCur = 0;

  /// 视频控制器
  VideoPlayerController? player;

  /// 数据
  var items = <Rx<JzxMediaData>>[];
  var orginItems = <JzxMediaData>[];

  /// 评论
  var commentList = <JzxCommentData>[];
  var isShowComment = false;
  Timer? timer;

  LifecycleEvent event = LifecycleEvent.invisible;

  @override
  void onInit() {
    super.onInit();
    getVideoList();

    // 过滤拉黑用户
    JzxAppService.bus.on<RefreshBlockUsers>().listen((event) {
      fliterUser();
    });
    JzxAppService.bus.on<RefreshFollowUsers>().listen((event) {
      followOrCancel(items[pageCur]);
    });
  }

  getVideoList() async {
    final paths = await JzxNetRepository.client.videoSearch(
      List.generate(
          15,
          (index) => {
                "mediaPath": "aface/lanlin/StickFlow/video/${index + 1}.mp4",
                "mediaType": "video"
              }),
    );

    orginItems = await JzxConfigService.to.getCurVideoList(paths);
    items = orginItems
        .where((element) =>
            !JzxConfigService.to.blockList.contains(element.user.userId))
        .map((e) => e.obs)
        .toList();
    initPlayer(items.first.value.url);

    update(['items']);

    showCommentWhenPlayingVideo(0);
  }

  /// 过滤用户
  fliterUser() async {
    await playOrPauseVideo(forcePause: true);
    items = orginItems
        .where((element) =>
            !JzxConfigService.to.blockList.contains(element.user.userId))
        .map((e) => e.obs)
        .toList();
    update(['items']);
  }

  @override
  void onClose() {
    disposePlayer();
    cancel();
    super.onClose();
  }

  /// 销毁当前播放
  disposePlayer() async {
    await playOrPauseVideo(forcePause: true);
    await player?.dispose();
    player = null;
  }

  /// 判断播放和暂停
  Future playOrPauseVideo({bool forcePause = false}) async {
    if (player == null) {
      return;
    }
    if (player!.value.isPlaying || forcePause) {
      await player!.pause();
    } else {
      // If the video is paused, play it.
      await player!.play();
    }
  }

  /// 切换播放
  void palyOhter(int index) {
    final temp = max(0, min(items.length - 1, index));
    if (items.isEmpty ||
        index >= items.length ||
        (event != LifecycleEvent.visible && event != LifecycleEvent.active)) {
      return;
    }

    .1.delay(() {
      pageController.jumpToPage(temp);
    });

    pageCur = temp;
    initPlayer(items[temp].value.url);
    showCommentWhenPlayingVideo(temp);
  }

  showCommentWhenPlayingVideo(int index) {
    // 渲染留言
    commentList = JzxConfigService.to
        .getCommentListById(items[index].value.id.toString(), pageType: 1);
    showComment();
  }

  /// 初始化控制器
  initPlayer(String url) async {
    // print(url);
    await disposePlayer();
    player = VideoPlayerController.networkUrl(
      Uri.parse(url),
      videoPlayerOptions: VideoPlayerOptions(
        mixWithOthers: true,
        allowBackgroundPlayback: false,
      ),
    )
      ..setLooping(true)
      ..addListener(() {
//         print('''
// ---------------
// $pageCur
// ${player!.value}
// ${player!.dataSource}
// ---------------
// ''');
        if (player?.value.hasError == true) {
          // print(player?.value.errorDescription);
          // print(player?.value.hasError);
          disposePlayer();
          initPlayer(url);
        }
        update(['video']);
      })
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        if (event == LifecycleEvent.active || event == LifecycleEvent.visible) {
          playOrPauseVideo();
        }
      });
  }

  /// 是否显示播放器
  bool showPlayer(int index, String url) {
    if (player == null || url != player?.dataSource) {
      return false;
    }

    if (!pageController.position.haveDimensions) {
      return false;
    }

    // 初始化成功 && 滚动状态 && 当前页
    return player!.value.position.inMicroseconds > 0 &&
        (pageController.page ?? 0) < index + 1 &&
        (pageController.page ?? 0) > index - 1 &&
        pageCur == index;
  }

  bool showPlayIcon() {
    if (player == null) {
      return true;
    }

    return !player!.value.isPlaying ||
        player!.value.position.inMicroseconds == 0;
  }

  /// 发送评论
  sendComment(JzxMediaData item) {
    final TextEditingController text = TextEditingController();
    Get.bottomSheet(
      CupertinoTextField(
        controller: text,
        autofocus: true,
        textInputAction: TextInputAction.send,
        style: myAppColors.black.font_16,
        placeholder: 'Send comments',
        padding: const EdgeInsets.all(12),
        decoration: const BoxDecoration(
          color: CupertinoDynamicColor.withBrightness(
            color: CupertinoColors.white,
            darkColor: CupertinoColors.black,
          ),
          borderRadius: BorderRadius.zero,
        ),
        onEditingComplete: () {
          Get.back();
          sendText(text.text);
        },
      ),
      useRootNavigator: true,
    );
  }

  /// 发送留言
  void sendText(String content, {int type = 0}) async {
    showLoading();
    await (Random().nextInt(2) + 1).delay();
    hideLoading();

    // JzxRCloudService.to.sendText(text.text);
    final postId = items[pageCur].value.id.toString();
    JzxCommentData item = JzxCommentData(
      content: content,
      postId: postId,
      id: '$postId-${JzxConfigService.to.commentsList.length + 1}',
      userId: JzxUserService.to.uid,
      nickname: JzxUserService.to.nickname,
      avatar: JzxUserService.to.avatar,
      level: JzxUserService.to.userWear.value,
      type: type,
      pageType: 1,
    );

    commentList.insert(0, item);
    JzxConfigService.to.updateCommentList(item);
    // 动效
    commentScorller.animateTo(
      0,
      duration: const Duration(milliseconds: 300),
      curve: Curves.easeOut,
    );
    showComment();
  }

  showComment() {
    if (!isShowComment && commentList.isNotEmpty) {
      isShowComment = true;
    }

    update(['comments']);
    cancel();
    timer = Timer.periodic(const Duration(seconds: 5), (timer) {
      cancel();
      isShowComment = false;
      update(['comments']);
    });
  }

  cancel() {
    timer?.cancel();
    timer = null;
  }

  void showOptions() {
    if (player == null || items.isEmpty) return;

    final item = items[pageCur];

    Get.bottomSheet(
      JzxOptionsSheet(
        item.value.user.userId,
        onBlock: () async {
          // playOrPauseVideo(forcePause: true);
          disposePlayer();
          WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
            palyOhter(pageCur);
          });
        },
      ),
      backgroundColor: Colors.white,
      isScrollControlled: true,
      barrierColor: myAppColors.barrierColor,
    );
  }

  void likeOrCancel(Rx<JzxMediaData> item) {
    final state = item.value.isLiked;
    if (state == false) {
      JzxUserService.to.updateUnlockConditions(3);
    }
    item.value = item.value.copyWith(
      isLiked: !state,
      like: item.value.like + (state ? -1 : 1),
    );
    // items[pageCur] = item;

    // update(['options']);
    //

    JzxConfigService.to.updateVideoList(item.value, canRefresh: true);
  }

  void followOrCancel(Rx<JzxMediaData> item) {
    item.value = item.value.copyWith(
      isFollowed: !item.value.isFollowed,
    );
    // showMessage(!item.value.isFollowed
    //     ? 'Unfollow Successfully'
    //     : 'Follow Successfully');
  }

  void followOrCancel2(Rx<JzxMediaData> item) async {
    showLoading();

    if (item.value.isFollowed) {
      await JzxNetRepository.client
          .removeFollow({'followUserId': item.value.user.userId});
    } else {
      await JzxNetRepository.client
          .addFollow({'followUserId': item.value.user.userId});
    }
    hideLoading();

    JzxConfigService.to.updateFollows(item.value.user.userId);

    showMessage(item.value.isFollowed
        ? 'Unfollow Successfully'
        : 'Follow Successfully');
  }
}
